package com.baike.controller;

import com.alibaba.fastjson.JSONObject;
import com.baike.data.Result;
import com.baike.em.ConstantEnum;
import com.baike.entity.TbLesson;
import com.baike.service.SearchService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("search")
@Api(value = "es全局搜索接口")
@RefreshScope
public class SearchController {

    @Autowired
    private RestHighLevelClient client;


    @ApiOperation("推送用户搜索查询 --> 标签名称")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lessonLabelName",value = "tb_lesson实体类lessonLabelName",required = true,paramType = "query"),
            @ApiImplicitParam(name = "pageNum",value = "起始页数",required = false,paramType = "query"),
            @ApiImplicitParam(name = "pageSize",value = "每页条数",required = false,paramType = "query")
    })
    @GetMapping("lessonLabelName")
    public Result getLessonLabelName(@RequestParam("lessonLabelName")String lessonLabelName,
                               @RequestParam(value = "pageNum",required = false)Integer pageNum,
                               @RequestParam(value = "pageSize",required = false)Integer pageSize){
        // 1.构建SearchRequest 对象 指定索引库
        SearchRequest searchRequest = new SearchRequest("baike");
        // 2.构建 SearchSourceBuilder 查询对象  --> 指定查询的条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 3.构建QueryBuilder查询对象   参数1.对应es索引库字段  2.查
        // 询的条件 传来的参数
        QueryBuilder builder = QueryBuilders.matchQuery("lesson_label_name",lessonLabelName);
//        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(lessonLabelName);// 带分析查询
        // 4.将QueryBuilder对象设置到SearchSourceBuilder中
        sourceBuilder.query(builder);
        if (pageNum !=null || pageSize != null){
            //设置分页
            sourceBuilder.from(pageNum);
            sourceBuilder.size(pageSize);
        }

        // 5.将SearchSourceBuilder对象封装到请求对象SearchRequest中
        searchRequest.source(sourceBuilder);
        // 6.调用方法进行数据通信
        SearchResponse response = null;
        List<TbLesson> list = new ArrayList<>();
        try {
            response = client.search(searchRequest, RequestOptions.DEFAULT);
            // 7.解析输出结果
            SearchHit[] hits = response.getHits().getHits();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                TbLesson tbLesson = JSONObject.parseObject(sourceAsString, TbLesson.class);
                list.add(tbLesson);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.build(ConstantEnum.SUCCESS).setResult(list);
    }


    @ApiOperation("首页搜索查询高亮展示")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lessName",value = "tb_lesson实体类lessName",required = true,paramType = "path"),
            @ApiImplicitParam(name = "pageNum",value = "起始页数",required = true,paramType = "path"),
            @ApiImplicitParam(name = "pageSize",value = "每页条数",required = true,paramType = "path")
    })
    @GetMapping("lessName/{lessName}/{pageNum}/{pageSize}")
    public Result getLessName(@PathVariable("lessName")String lessName,@PathVariable("pageNum")Integer pageNum,
                               @PathVariable("pageSize")Integer pageSize){
        //设置请求对象 设置查询的字段进行查询
        SearchRequest searchRequest = new SearchRequest("baike");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //搜索title标题
        QueryBuilder builder = QueryBuilders.matchQuery("lesson_name", lessName);
        searchSourceBuilder.query(builder);
        //设置一下排序 默认是升序 可以不写
//        searchSourceBuilder.sort("id");
        //设置要高亮的字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("lesson_name");
        //设置高亮的样式
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        //设置分页
        searchSourceBuilder.from(pageNum);
        searchSourceBuilder.size(pageSize);

        searchSourceBuilder.highlighter(highlightBuilder);
        searchRequest.source(searchSourceBuilder);

        //数据准备
        Map<String,Object> map = new HashMap<>();
        List<TbLesson> list = new ArrayList<>();
        long totalHits = 0;
        try {
            //调用方法进行通讯
            SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
            //获取结果  // 所有命中的数据
            SearchHit[] hits = response.getHits().getHits();
            //获取总条数
            totalHits = response.getHits().getTotalHits();


            for (SearchHit hit : hits) {
                //获取普通的内容
                String jsonString = hit.getSourceAsString();
                //转为对象
                TbLesson lesson = JSONObject.parseObject(jsonString, TbLesson.class);
                //获取高亮的字段
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                //解析高亮结果
                HighlightField highlightField = highlightFields.get("lesson_name");
                // 回去的每一条  高亮的数据
                Text[] fragments = highlightField.getFragments();
                for (Text text : fragments) {
                    //获取本次高亮的字段,并设置给实体类
                    lesson.setLessonName(text.toString());
                }
                list.add(lesson);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        //返回结果
        map.put("items",list);
        map.put("total",totalHits);
        System.err.println(map);
        return Result.build(ConstantEnum.SUCCESS).setResult(map);
    }
}
